package duplas;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Main {
	
	
	public static void main(String[] args) throws IOException {
		PosicaoSemana posicao = null;
//		PosicaoSemana.excluirSemana(15);
//		PosicaoSemana.serializa();
//		posicao = PosicaoSemana.ultimaPosicao();
		
		
//		if (possui(args, "-r")) {
//			RestricaoPadrao restricao = carregaRestricao(pegaParametro(args, "-r"));
//			posicao = posicionamentoProximaSemana(restricao);
//			//System.out.println(restricao);
//		}
		
//		if (possui(args, "-a")) {
//			acertaPosicoesComArquivo(pegaParametro(args, "-a"));
//		}
		
		
		posicao = PosicaoSemana.ultimaPosicao();	
		
		//PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		
		//PosicaoSemana posicao = duplaSemana8();
		
		/*if (possui(args, "-i")) {
			init();
		}
		
		PosicaoSemana posicao = null;
		if (possui(args, "-p")) {
			posicao = PosicaoSemana.pesquisaDadoSemana(Integer.parseInt(pegaParametro(args, "-p")));
		}
		
		if (possui(args, null) || possui(args, "-u")){
			posicao = calculaUltimaPosicao();
		}
		
//		if (possui(args, "-r")) {			
//			posicao = calculaPosicaoComRestricao(Integer.parseInt(pegaParametro(args, "-r")));
//		}
		
		if (possui(args, "-L")) {			
			excluirPosicoesAPartirDaSemana(Integer.parseInt(pegaParametro(args, "-L")));
		}
		
		if (possui(args, "-U")) {
			posicao = PosicaoSemana.ultimaPosicao();
			//corrigir(posicao);
		}
		*/
		System.out.println(posicao == null ? "fim" : posicao);
	}

	private static void acertaPosicoesComArquivo(String filePath) {
		
		try {
			Scanner s = new Scanner(new File(filePath));
			if (!s.hasNextLine()) System.out.println("afe"); 
			PosicaoSemana posicao = parseSemana(s.nextLine());
			System.out.println("Antes \n" + posicao);
			while ( s.hasNextLine() ) {				
				String linha = s.nextLine();
				if (linha.trim().length() == 0) continue;
				Dupla d = criaDuplaString(linha, "\\) #| #");
				if (!posicao.isDuplaAlocadaCorretamente(d))
					posicao.insereDupla(d);
			}
			
			PosicaoSemana.serializa();
			System.out.println("Depois \n" + posicao);
			
		} catch (FileNotFoundException e) {			
			e.printStackTrace();
		}		
	}

	private static PosicaoSemana parseSemana(String cabecalho) {
		Integer numeroSemana = Integer.valueOf(cabecalho.split(" ")[3]);
		PosicaoSemana posicao = PosicaoSemana.pesquisaDadoSemana(numeroSemana);
		if (posicao == null) 
			throw new RuntimeException("Semana nao encontrada! " + numeroSemana);
		return posicao;
	}

	private static RestricaoPadrao carregaRestricao(String filePath) {
		RestricaoPadrao restricao = new RestricaoPadrao();
		try {
			Scanner s = new Scanner(new File(filePath));			
			while ( s.hasNextLine() ) {				
				restricao.adicionaDupla(criaDuplaString(s.nextLine(), " #"));
			}
				
			
		} catch (FileNotFoundException e) {			
			e.printStackTrace();
		}
		return restricao;
	}

	private static Dupla criaDuplaString(String string, String pattern) {
		String[] bah = string.split(pattern);
		return new Dupla(bah[1], bah[2], Integer.parseInt(bah[0]));
	}

	private static void corrigir(PosicaoSemana posicao) {
		
		ArrayList<String> dupla5 = posicao.getPosicoes().get(4);
		ArrayList<String> dupla6 = posicao.getPosicoes().get(5);
		ArrayList<String> dupla12 = posicao.getPosicoes().get(11);
		
		String tmp = dupla5.get(0);
		dupla5.remove(0);	
		dupla5.add(0, dupla12.get(1));
		
		String tmp2 = dupla6.get(1);
		dupla6.remove(1);
		dupla6.add(1, tmp);
		
		dupla12.remove(1);
		dupla12.add(1, tmp2);
		
		PosicaoSemana.serializa();
	}

	private static PosicaoSemana duplaSemana6() {
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoPadrao restricao = new RestricaoPadrao(new Dupla("Tomazini", "Anderson", 0));
		restricao.adicionaDupla(new Dupla("Guto", "Lemão", 1));
		restricao.adicionaDupla( new Dupla("Ednardo", "M. Vinicius", 2));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}
	
	private static PosicaoSemana duplaSemana7() {
		PosicaoSemana posicao = PosicaoSemana.pesquisaDadoSemana(6);
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoPadrao restricao = new RestricaoPadrao(new Dupla("Tomazini", "Eduardo", 0));
		restricao.adicionaDupla(new Dupla("Guto", "VW", 1));
		restricao.adicionaDupla( new Dupla("Ednardo", "Geraldo", 2));
		restricao.adicionaDupla( new Dupla("Anderson", "GB", 4));
		restricao.adicionaDupla( new Dupla("Julio", "Arion", 9));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}
	
	private static PosicaoSemana posicionamentoProximaSemana(RestricaoPadrao restricao) {
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();	
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
				
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}
	
	
	private static PosicaoSemana duplaSemana8() {
		PosicaoSemana posicao = PosicaoSemana.pesquisaDadoSemana(7);
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoPadrao restricao = new RestricaoPadrao(new Dupla("Zarpa", "Eduardo", 0));
		restricao.adicionaDupla(new Dupla("Diego", "VW", 1));
		restricao.adicionaDupla( new Dupla("Zambrana", "Geraldo", 2));
		restricao.adicionaDupla( new Dupla("Anderson", "GB", 4));
		restricao.adicionaDupla( new Dupla("Julio", "Arion", 9));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}
	
	/*private static PosicaoSemana duplaSemana3() {
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoCST restricao = new RestricaoCST(new Dupla("Arion", "Anderson", 11));
		restricao.adicionaDupla(new Dupla("Dog", "Lemão", 12));
		restricao.adicionaDupla( new Dupla("Tio Xico", "M. Vinicius", 13));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}*/
	
	
	/*private static PosicaoSemana duplaSemana3() {
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(proximaSemana);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoCST restricao = new RestricaoCST(new Dupla("Arion", "GB", 11));
		restricao.adicionaDupla(new Dupla("Dog", "Menegazzo", 12));
		restricao.adicionaDupla( new Dupla("Tio Xico", "Taborda", 13));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}*/
	
	
	private static PosicaoSemana novasDuplas() {
		init2();
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);
		
		ArrayList<DuplaSemana> novasDuplas = DuplaSemana.getTodos().get(2);
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());
		
		RestricaoPadrao restricao = new RestricaoPadrao(new Dupla("Robson", "Nathan", 11));
		restricao.adicionaDupla(new Dupla("Herminio", "Cassio", 12));
		restricao.adicionaDupla( new Dupla("Palilo", "Egidio", 13));
		posicionamento.adicionaRestricao(restricao);
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}

	private static void excluirPosicoesAPartirDaSemana(int semana) {
		PosicaoSemana posicao = PosicaoSemana.pesquisaDadoSemana(semana);
		while (posicao != null){
			PosicaoSemana.excluirSemana(posicao.getSemana());			
			posicao = PosicaoSemana.pesquisaDadoSemana(++semana);
		}
		PosicaoSemana.serializa();
	}


	private static String pegaParametro(String[] args, String string) {
		return args[pegaIndice(args, string) + 1];
	}

	private static PosicaoSemana calculaUltimaPosicao() throws IOException {
		PosicaoSemana posicao = PosicaoSemana.ultimaPosicao();
		Integer proximaSemana = posicao.getSemana() + 1;
		Integer quemAnda = (posicao.getQuemAndou() == 0 ? 1 : 0);

		Map<String, String> novasDuplas = new Utils().leArquivo(proximaSemana.toString());
		PosicionamentoDuplas posicionamento = new PosicionamentoDuplas(posicao.getPosicoesCopia());		
		
		List<ArrayList<String>> novasPosicoes = posicionamento.alocarNovasDuplas(novasDuplas, quemAnda);
		PosicaoSemana novaPosicao = new PosicaoSemana(proximaSemana, quemAnda, novasPosicoes);
		PosicaoSemana.serializa();
		return novaPosicao;
	}

	public static boolean possui(String[] parametros, String entrada) {
		if (entrada == null) return parametros.length == 0;
		return pegaIndice(parametros, entrada) != -1;
	}
	
	public static Integer pegaIndice(String[] parametros, String entrada) {
		for (int i = 0; i < parametros.length; i++)
			if (entrada.equals(parametros[i]))
				return i;
		return -1;
	}

	public static void init() {
		ArrayList<ArrayList<String>> posicoesAnteriores = new ArrayList<ArrayList<String>>();

		ArrayList<String> dupla = new ArrayList<String>();
		dupla.add("Zarpa");
		dupla.add("Dudu");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Zulin");
		dupla.add("Eduardo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Matheus");
		dupla.add("Ednardo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Zambrana");
		dupla.add("Erick");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("GB");
		dupla.add("Guto");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Palilo");
		dupla.add("Marrony");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Bruno Rogério");
		dupla.add("M. Menegazzo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Herminio");
		dupla.add("Lohandus");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("M. Machado");
		dupla.add("Geraldo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Francis");
		dupla.add("Nathan");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Egidio");
		dupla.add("Fernando");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("M. Vinicius");
		dupla.add("Roberson");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Michel Ruiz");
		dupla.add("Gabriel de O.");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Julio");
		dupla.add("Luiz Taborda");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Cachorro");
		dupla.add("Anderson");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Robson");
		dupla.add("Guilherme (Lemão)");
		posicoesAnteriores.add(dupla);

		new PosicaoSemana(18, 1, posicoesAnteriores);
		PosicaoSemana.serializa();
	}
	
	public static void init2() {
		ArrayList<ArrayList<String>> posicoesAnteriores = new ArrayList<ArrayList<String>>();

		ArrayList<String> dupla = new ArrayList<String>();
		dupla.add("Luis");
		dupla.add("Tomazini");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Menegazzo");
		dupla.add("Maycon");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Palilo");
		dupla.add("Fernanda");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Taborda");
		dupla.add("M. Vinicius");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Matheus");
		dupla.add("Nathan");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Anderson");
		dupla.add("Marrony");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Robson");
		dupla.add("Geraldo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Ednardo");
		dupla.add("VW");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Lemão");
		dupla.add("Zambrana");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Arion");
		dupla.add("Eduardo");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Ruiz");
		dupla.add("Zulin");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("GB");
		dupla.add("Julio");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Erick");
		dupla.add("Cassio");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Zarpa");
		dupla.add("Egidio");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Dudu");
		dupla.add("Guto");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Maromba");
		dupla.add("Heron");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Herminio");
		dupla.add("Tio Xico");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Dog");
		dupla.add("Fernando");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Lohandus");
		dupla.add("Francis");
		posicoesAnteriores.add(dupla);
		dupla = new ArrayList<String>();
		dupla.add("Roberson");
		dupla.add("Diego");
		posicoesAnteriores.add(dupla);

		PosicaoSemana.limpar();
		new PosicaoSemana(1, 1, posicoesAnteriores);
		PosicaoSemana.serializa();
	}

}
